<template>
  <div ref="root" style="position: absolute; font-size: 14px" />
</template>

<script lang="ts">
const defaultOptions = {
  useWrapMode: false,
  enableSnippets: true,
  useWorker: false,
  enableLiveAutocompletion: true,
  enableBasicAutocompletion: true,
  tabSize: 2,
  // Jie. 20250524 自定义代码提示
  fontSize: 14,
};
</script>

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { edit, Ace } from 'ace-builds';
import { ANY_OBJECT } from '@/types/generic';
// Jie. 20250524 自定义代码提示
import * as Completers from '@/common/utils/completer';
import JSBeautify from 'js-beautify';
// 引入对应的mode
import 'ace-builds/src-noconflict/mode-javascript';
import 'ace-builds/src-noconflict/snippets/javascript';

// 引入对应的theme
//import 'ace-builds/src-noconflict/theme-xcode';
// 如果要有代码提示，下面这句话必须引入!!!
// Jie. 20250524 打开这个就有代码提示了
import 'ace-builds/src-noconflict/ext-language_tools';
import 'ace-builds/src-noconflict/worker-javascript';

const emit = defineEmits<{ 'update:value': [string]; save: [] }>();

const props = withDefaults(
  defineProps<{
    value?: string;
    type?: string;
    options?: ANY_OBJECT;
    completer?: ANY_OBJECT;
  }>(),
  {
    type: 'javascript',
    options: () => {
      return defaultOptions;
    },
  },
);
const root = ref();
let editor: Ace.Editor | null = null;

watch(
  () => props.value,
  newValue => {
    //console.log('value change', newValue);
    if (editor && editor.getValue() !== newValue) {
      editor.setValue(newValue || '');
      editor.moveCursorTo(0, 0);
    }
  },
  {
    deep: true,
    immediate: true,
  },
);

onMounted(() => {
  let finalOptions: ANY_OBJECT = {
    ...defaultOptions,
    ...props.options,
  };
  // TODO 语法检查与错误提示
  editor = edit(root.value, finalOptions);
  // 设置mode为module以支持连续点号触发
  editor.getSession().setMode('ace/mode/javascript');
  editor.session.setMode('ace/mode/javascript');

  // Jie. 20250524 添加自定义代码提示
  const langTools = (window as any).ace.require('ace/ext/language_tools');
  const snippetManager = (window as any).ace.require('ace/snippets').snippetManager;

  // 添加自定义代码片段
  snippetManager.register(Completers.customSnippet, 'javascript');

  // 确保语言工具被正确配置
  editor.setOptions({
    enableBasicAutocompletion: true,
    enableSnippets: true,
    enableLiveAutocompletion: true,
  });

  // 添加所有completer
  langTools.addCompleter(Completers.instanceCompleter);

  editor.getSession().on('change', () => {
    if (editor) {
      emit('update:value', editor.getValue());
    }
  });
  if (props.value) editor.setValue(props.value);
  // 快捷键
  editor.commands.addCommand({
    name: 'saveCommand',
    bindKey: { win: 'Ctrl-S', mac: 'Command-S' },
    exec: editor => {
      emit('save');
    },
  });
});

// Jie. 20250524 监听 completer 变化
watch(
  () => props.completer,
  newCompleter => {
    if (editor && newCompleter && typeof newCompleter.getCompletions === 'function') {
      const langTools = (window as any).ace.require('ace/ext/language_tools');
      // 添加新的 completer
      langTools.addCompleter(newCompleter);
    }
  },
  { deep: true },
);

onBeforeUnmount(() => {
  if (editor) {
    editor.destroy();
    editor.container.remove();
    editor = null;
  }
});

// Jie. 20250526 格式化代码
const formatCode = () => {
  // 获取编辑器中的代码
  if (!editor) return;
  var code = editor.getValue();
  var beautifiedCode = JSBeautify.js_beautify(code);
  editor.setValue(beautifiedCode);
};

defineExpose({ formatCode });
</script>
